package com.iwhalecloud.bss.kite.cucc.web.controller.scene;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.iwhalecloud.bss.kite.cart.client.api.cart.query.IQueryKiteShoppingCartService;
import com.iwhalecloud.bss.kite.cart.common.constant.KiteCartKeyConsts;
import com.iwhalecloud.bss.kite.client.api.scene.query.IQuerySceneService;
import com.iwhalecloud.bss.kite.client.dto.DataResult;
import com.iwhalecloud.bss.kite.client.dto.accept.in.AcceptRequestInDTO;
import com.iwhalecloud.bss.kite.client.vo.scene.ProductModuleVO;
import com.iwhalecloud.bss.kite.client.vo.scene.SceneVO;
import com.iwhalecloud.bss.kite.common.constant.ErrorConsts;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts3;
import com.iwhalecloud.bss.kite.common.constant.ServiceOfferConsts;
import com.iwhalecloud.bss.kite.common.constant.SwitchConsts;
import com.iwhalecloud.bss.kite.common.log.KiteLogEnum;
import com.iwhalecloud.bss.kite.common.log.KiteLogger;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteMapUtils;
import com.iwhalecloud.bss.kite.common.util.KiteObjectUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.client.api.flow.IFlowService;
import com.iwhalecloud.bss.kite.cucc.client.api.goods.IGoodsService;
import com.iwhalecloud.bss.kite.cucc.client.api.order.IReceiptService;
import com.iwhalecloud.bss.kite.cucc.client.api.scene.ICuccSceneService;
import com.iwhalecloud.bss.kite.cucc.client.api.shoppingcart.operate.ICuccOperateShoppingCartService;
import com.iwhalecloud.bss.kite.cucc.client.api.shoppingcart.query.ICuccQueryShoppingCartService;
import com.iwhalecloud.bss.kite.cucc.client.dto.scene.PageNavigationReqDTO;
import com.iwhalecloud.bss.kite.cucc.client.vo.scene.OneStopTrackInfoVO;
import com.iwhalecloud.bss.kite.cucc.client.vo.scene.OssTrackInfoVO;
import com.iwhalecloud.bss.kite.cucc.client.vo.scene.ReceiptInfoVO;
import com.iwhalecloud.bss.kite.cucc.client.vo.scene.SceneNewOfferSeneVO;
import com.iwhalecloud.bss.kite.cucc.client.vo.scene.TrackInfoVO;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalServiceOfferConsts;
import com.iwhalecloud.bss.kite.cucc.dataservice.cache.CuccOfferOriginalInfoCache;
import com.iwhalecloud.bss.kite.cucc.manager.cache.CuccExtParameterCache;
import com.iwhalecloud.bss.kite.cucc.service.even.GroupProdAttrEvent;
import com.iwhalecloud.bss.kite.cucc.service.even.KiteCartStatusModifyEvent;
import com.iwhalecloud.bss.kite.cucc.web.service.accept.service.CuccKitePageNavigationCache;
import com.iwhalecloud.bss.kite.cucc.web.service.scene.PageNavigationService;
import com.iwhalecloud.bss.kite.dataservice.cache.DcPublicCache;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferAttrCache;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferCache;
import com.iwhalecloud.bss.kite.dataservice.cache.ProductCache;
import com.iwhalecloud.bss.kite.dataservice.entity.DcPublic;
import com.iwhalecloud.bss.kite.dataservice.entity.OfferAttr;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.Offer;
import com.iwhalecloud.bss.kite.dataservice.util.GeneralSwitchUtils;
import com.iwhalecloud.bss.kite.manager.api.IOperateSceneInstService;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.enums.InstType;
import com.iwhalecloud.bss.kite.manager.inst.KiteOfferInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteSceneInst;
import com.iwhalecloud.bss.kite.manager.inst.graph.IInstVertex;
import com.iwhalecloud.bss.kite.manager.transaction.KiteTransactional;
import com.iwhalecloud.bss.kite.manager.transaction.TransactionContext;
import com.iwhalecloud.bss.kite.web.context.KiteWebContext;
import com.iwhalecloud.bss.kite.web.service.accept.service.KitePageNavigationCache;
import com.iwhalecloud.bss.kite.web.service.accept.service.SceneVOCache;
import com.iwhalecloud.bss.kite.web.service.accept.vo.PageNavigationVO;
import com.iwhalecloud.bss.kite.web.service.scene.ISceneService;
import com.ztesoft.bss.common.bo.LoginInfo;
import com.ztesoft.bss.common.util.ContextUtil;
import com.ztesoft.bss.common.util.SpringUtil;
import com.ztesoft.bss.common.util.StringUtil;
import com.ztesoft.common.logger.api.ZLogger;
import com.ztesoft.common.logger.factory.ZLoggerFactory;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

/**
 * <Description> 场景受理 <br>
 *
 * @author huang.caibiao <br>
 * @version 1.0<br>
 * @see com.iwhalecloud.bss.kite.web.controller.order <br>
 * @since R9.0<br>
 */
@RestController("cuccScene")
@RequestMapping("/cuccScene")
@Api(tags = {"/cuccScene - 场景受理，返回页面展示对象,兼容新增和购物车修改过来，从购物车过来只有sceneInstId、templateId、serviceOfferId"
}, description = "初始化在SceneInitController")
public class SceneController {

    private static final ZLogger LOGGER = ZLoggerFactory.getLogger(SceneController.class, KeyConsts.LOG_MODULE);

    @Autowired
    private ISceneService sceneService;

    @Autowired
    private ICuccSceneService cuccSceneService;

    @Autowired
    private IQuerySceneService querySceneService;

    @Autowired
    private IQuerySceneInstService querySceneInstService;

    @Autowired
    private PageNavigationService pageNavigationService;

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private IFlowService queryFlowService;

    @Autowired
    private IReceiptService queryReceiptService;

    @Autowired
    private IOperateSceneInstService operateSceneInstService;

    @Autowired
    private ICuccOperateShoppingCartService operateShoppingCartService;

    @Autowired
    private ICuccQueryShoppingCartService queryShoppingCartService;

    @Autowired
    private IGoodsService goodService;

    @KiteTransactional
    @ApiOperation(value = "草稿状态清理缓存数据", notes = "草稿状态清理缓存数据")
    @ApiImplicitParams({@ApiImplicitParam(name = "offerId", value = "销售品标识"),
        @ApiImplicitParam(name = "templateId", value = "场景模板标识", required = true),
        @ApiImplicitParam(name = "sceneInstId", value = "场景实例标识", required = true)
    })
    @GetMapping("clearDraftCache")
    public DataResult clearCache(@RequestParam(required = false) String offerId,
                                                       @RequestParam String sceneInstId, @RequestParam String templateId, @RequestParam(required = false) String cartId, @RequestParam(required = false) String custId, @RequestParam(required = false) String type) {
        // 如果是草稿装则从新读取数据库
        String status = operateShoppingCartService.getShoppingCartGroupInstStatusByCartId(sceneInstId, custId, cartId);

        if (KiteCartKeyConsts.SHOPPING_CART_GROUP_STATUS_DRAFT.equals(status)) {

            try {
                KiteSceneInst kiteSceneInst = TransactionContext.getContainer().getSceneInst(sceneInstId);
                if (Objects.nonNull(kiteSceneInst)) {
                    final Map<String, IInstVertex> instVertexMap = kiteSceneInst.getInstRelGraph().getInstVertexMap();
                    instVertexMap.forEach((s, iInstVertex) -> {
                        TransactionContext.getContainer().getCustInstRelGraph(custId).removeVertex(iInstVertex.getInstType(), iInstVertex.getInstId());
                    });
                    TransactionContext.getContainer().deleteSceneInst(sceneInstId);
                }
            }
            catch (Exception e) {
                LOGGER.warn(e.getMessage());
            }
        }
        return ErrorConsts.SUCCESS.getResult(Boolean.TRUE);
    }

    @KiteTransactional
    @ApiOperation(value = "生成新增套餐场景对象", notes = "生成新增套餐场景对象")
    @ApiImplicitParams({@ApiImplicitParam(name = "offerId", value = "销售品标识"),
        @ApiImplicitParam(name = "templateId", value = "场景模板标识", required = true),
        @ApiImplicitParam(name = "sceneInstId", value = "场景实例标识", required = true)
    })
    @GetMapping
    public DataResult<SceneVO> createNewOfferSceneInst(@RequestParam(required = false) String offerId,
                                                       @RequestParam String sceneInstId, @RequestParam String templateId, @RequestParam(required = false) String cartId, @RequestParam(required = false) String custId, @RequestParam(required = false) String type) {
        //  KiteSceneInst sceneInst = getSceneInst(sceneInstId);
        LoginInfo loginInfo = ContextUtil.getLoginInfo();
        Map<String, Object> extParams = loginInfo.getUserInfo().getExtParams();
        if (KiteMapUtils.isNotEmpty(extParams) && !KiteStringUtils.isEmpty(cartId)) {
            extParams.put("KITE_SCENEINST_CARTID", cartId);
            ContextUtil.setLoginInfo(loginInfo);
        }
        if (KiteStringUtils.isEmpty(custId)) {
            custId = KiteWebContext.getContext().getCustId();
        }

        KiteSceneInst sceneInst = this.querySceneInstService
            .getSceneInst(sceneInstId, custId);
        if (KiteStringUtils.isNotEmpty(type)) {
            // 挂起解挂时新增标识
            operateSceneInstService.putExtParameter(sceneInstId, "lockOrReleaseOpType", type);
        }
        String serviceOfferId = sceneInst.getServiceOfferId();
        if (InstType.PROD_INST.equals(sceneInst.getRootInstType())) {
            //基础销售品
            offerId = ProductCache.get(getSpecId(sceneInst)).getBaseOfferId();
        } else {
            offerId = getSpecId(sceneInst);
        }

        // 增加标识，当前是否为页面初始化渲染（如进入签订页面），忽略 Handler 的属性校验报错，否则会因为属性值校验不通过，导致页面渲染中断
        operateSceneInstService.putExtParameter(sceneInstId, "isInitPageRenderFlag", LocalKeyConsts.IFTRUE_T);

        AcceptRequestInDTO acceptRequest = new AcceptRequestInDTO();
        acceptRequest.setSceneInstId(sceneInstId).setSceneTemplateId(templateId).setOfferId(offerId)
            .setServiceOfferId(serviceOfferId);
        DataResult<SceneVO> sceneVoResult = sceneService.callEngine(acceptRequest);
        // 初始化完毕，移除 页面初始化渲染 标识
        operateSceneInstService.removeExtParameter(sceneInstId, "isInitPageRenderFlag");

        //发布属性分组处理事件
        SceneNewOfferSeneVO sceneVO = (SceneNewOfferSeneVO) sceneVoResult.getResultObject();
        List<ProductModuleVO> productModuleVOList = sceneVO.getSceneProductModuleVO().getProduct();
        Collections.reverse(productModuleVOList);
        GroupProdAttrEvent groupProdAttrEvent = new GroupProdAttrEvent(this, custId, "");
        groupProdAttrEvent.setSceneInstId(sceneInstId);
        groupProdAttrEvent.setProductModuleVOList(productModuleVOList);
        applicationContext.publishEvent(groupProdAttrEvent);
//        放置重要提醒
        String tacheCode = (String) CuccExtParameterCache.getExtParameter(sceneInstId, custId, cartId).get("nodeCode");
        if (sceneVO.getSceneProductModuleVO().getOffer().getOfferInstList().size() > 0) {
            List<DcPublic> dcPublics = DcPublicCache.getByPcode("2021102709", "importantReminder", sceneVO.getSceneProductModuleVO().getOffer().getOfferInstList().get(0).getOfferId());
            if (dcPublics.size() > 0 && dcPublics.get(0).getCodeb().contains(serviceOfferId)) {
                String upstreamOrderId = querySceneInstService.getExtParameterValue(sceneInstId, "upstreamOrderId");
                if (KeyConsts3.ORDER_SIGNED.equals(tacheCode) && StringUtils.isNotBlank(upstreamOrderId)) {
                    sceneVO.setImportantReminder(dcPublics.get(0).getCodea());
                } else if (null == tacheCode&&serviceOfferId.equals(1)) {
                    sceneVO.setImportantReminder(dcPublics.get(0).getCodea());
                }
            }
        }
        //5G纯数据 集团名单制客户或外省名单制客户，页面上弹窗提示
        if (KiteStringUtils.equalsAny(offerId, "10004322", "50040896") && KiteStringUtils.equals(serviceOfferId, ServiceOfferConsts.SERVICE_OFFER_ORDER)) {
            Map verifyCustRsp = querySceneInstService.getExtParameterValue(sceneInstId, "VERIFY_CUST_RSP");
            if (KiteMapUtils.isNotEmpty(verifyCustRsp)) {
                String respDesc = (String) verifyCustRsp.get("RESP_DESC");
                String respCode = (String) verifyCustRsp.get("RESP_CODE");
                if (KiteStringUtils.equalsAny(respCode, "0", "1") && KiteStringUtils.isNotEmpty(respDesc)) {
                    sceneVO.setImportantReminder(respDesc);
                }
            }
        }

        //发布状态修改事件-场景数据来源为订单中心的不需要保存购物车，不需要修改购物车状态
        String askSource = this.querySceneInstService.getSceneInst(sceneInstId).getAskSource();
        String saveCartFlag = querySceneInstService.getExtParameterValue(sceneInstId, "saveCart");
        if (!KiteStringUtils.equals(LocalKeyConsts.ASK_SOURCE_ORDER, askSource) && KiteStringUtils.isEmpty(saveCartFlag)) {
            this.operateSceneInstService.putExtParameter(sceneInstId, "saveCart", "saveCart");
            com.iwhalecloud.bss.kite.cucc.web.service.ISceneService cuccSceneService = SpringUtil.getBean(com.iwhalecloud.bss.kite.cucc.web.service.ISceneService.class);
            cuccSceneService.cacheShoppingCartGroup(sceneInstId, sceneInst.getCartId());
        }
        this.operateSceneInstService.putExtParameter(sceneInstId, LocalKeyConsts.BUSI_CHANGE_SCENE_ONE, "F");
        return sceneVoResult;
    }

    @ApiOperation(value = "获取页面导航对象", notes = "获取页面导航对象")
    @ApiImplicitParams({@ApiImplicitParam(name = "serviceOfferId", value = "服务提供标识", required = true),
        @ApiImplicitParam(name = "offerType", value = "销售品类型", required = true),
        @ApiImplicitParam(name = "offerId", value = "销售品标识", required = false),
        @ApiImplicitParam(name = "sceneInstId", value = "场景实例id", required = false)
    })
    @GetMapping(value = "/navigation")
    @KiteLogger(isWrite = true, type = KiteLogEnum.CONTROLLER)
    public DataResult<PageNavigationVO> getPageNavigation(@RequestParam String serviceOfferId,
        @RequestParam(required = false) String offerType, @RequestParam(required = false) String offerId,
        @RequestParam(required = false) String sceneInstId, @RequestParam(required = false) String singleGoodsSku,
        @RequestParam(required = false) String receptionType) {
        if (KiteStringUtils.isEmpty(sceneInstId)) {
            sceneInstId = KiteWebContext.getContext().getCurrentSceneInstId();

            if (KiteStringUtils.isNotEmpty(sceneInstId)) {
                String renderOrderType = querySceneInstService.getExtParameterValue(sceneInstId, "renderOrderType");
                if (KiteStringUtils.isEqual(renderOrderType, "orderRejection")) {
                    sceneInstId = null;
                }
            }
        }
        String oldServiceOfferId = serviceOfferId;
        if (GeneralSwitchUtils.isSwitchOpened("CUCC_KITE_PAGE_NAVIGATION")) {
            String custId = KiteWebContext.getContext().getCustId();
            String cartId = this.cuccSceneService.getCartIdFromES().getResultObject();
            // 取销售商品下的商品类型
            Map<String, Object> goodsInfo = CuccOfferOriginalInfoCache.get(offerId);
            List<Map<String, Object>> saleGoods = KiteMapUtils.getValue(goodsInfo, "saleGoods");
            if (!KiteListUtils.isEmpty(saleGoods)) {
                String finalOfferType = offerType;
                List<String> offerTypes = saleGoods.stream().map(map -> {
                    String goodsSku = KiteMapUtils.getString(map, "goodsSku");
                    if (Objects.nonNull(OfferCache.get(goodsSku))) {
                        return OfferCache.get(goodsSku).getOfferType();
                    } else {
                        return finalOfferType;
                    }

                }).collect(Collectors.toList());
                offerType = Collections.max(offerTypes);
                if (KiteStringUtils.isEmpty(singleGoodsSku)) {
                    singleGoodsSku = KiteMapUtils.getString(saleGoods.get(0), "goodsSku");
                }
            } else {
                offerType = OfferCache.get(offerId).getOfferType();
            }

            // 新配置，如果旧配置信息取不到则取新配置
            //String taskCode = this.querySceneInstService.getExtParameterValue(sceneInstId, "taskCode");
            //String tacheCode = this.querySceneInstService.getExtParameterValue(sceneInstId, "nodeCode");
            String taskCode = (String) CuccExtParameterCache.getExtParameter(sceneInstId, custId, cartId).get("taskCode");
            String tacheCode = (String) CuccExtParameterCache.getExtParameter(sceneInstId, custId, cartId).get("nodeCode");
            // 为空则认为是录入
            if (KiteStringUtils.isEmpty(tacheCode)) {
                tacheCode = "OrderInput";
            }
            if (KiteStringUtils.isEmpty(singleGoodsSku)) {
                singleGoodsSku = offerId;
            }

            // 服务提供
            //String serviceOfferIdStr = this.querySceneInstService.getExtParameterValue(sceneInstId, "serviceOfferId");
            String serviceOfferIdStr = (String) CuccExtParameterCache.getExtParameter(sceneInstId, custId, cartId).get("serviceOfferId");
            if (LocalServiceOfferConsts.SERVICE_OFFER_FOLLOW.equals(oldServiceOfferId)) {
                //String upServiceOfferId = this.querySceneInstService.getExtParameterValue(sceneInstId, "upServiceOfferId");
                String upServiceOfferId = (String) CuccExtParameterCache.getExtParameter(sceneInstId, custId, cartId).get("upServiceOfferId");
                if (KiteStringUtils.isNotEmpty(upServiceOfferId)) {
                    oldServiceOfferId = upServiceOfferId;
                    tacheCode = "OrderChase";
                } else if (!KiteStringUtils.equalsAny(serviceOfferIdStr, "1001", "1012")) {
                    // 非产品变更的二次类业务追单,支持用自身的服务提供配置模板
                    oldServiceOfferId = serviceOfferIdStr;
                    tacheCode = "OrderChase";
                }
            }
            // 趸交支付详情
            String payDetailFlag = (String) CuccExtParameterCache.getExtParameter(sceneInstId, custId, cartId).get("PAY_DETAIL_FLAG");
            if (KiteStringUtils.isNotEmpty(payDetailFlag) && KiteStringUtils.equals(payDetailFlag, "T")) {
                tacheCode = "PayDetail";
            }
            // 趸交返销
            String resaleFlag = (String) CuccExtParameterCache.getExtParameter(sceneInstId, custId, cartId).get("SCENE_RESALE");
            if (KiteStringUtils.equals(resaleFlag, "resale")) {
                tacheCode = "OrderResale";
            }
            Offer offer = OfferCache.get(offerId);
            if (Objects.nonNull(offer) && KiteStringUtils.isEmpty(offerType)) {
                offerType = offer.getOfferType();
            }
            // 批量受理订购
            if (KiteStringUtils.equals(receptionType, "batchReception")) {
                tacheCode = "BatchInput";
            }
            String objId = "";
            if (Objects.nonNull(offer) && KiteStringUtils.isEmpty(objId)) {
                objId = offer.getCateId();
            }

            List<OfferAttr> offerAttrs = OfferAttrCache.get(offerId);
            if (KiteStringUtils.isEmpty(objId) && !KiteListUtils.isEmpty(offerAttrs)) {
                OfferAttr catIdAttr = offerAttrs.stream().filter(attr -> "cateId".equals(attr.getFieldName())).findAny()
                    .orElse(new OfferAttr());
                objId = catIdAttr.getDefaultValue();
            }
            // 1、先根据任务编码获取（环节编码不满足一个环节多个任务的模板配置要求） 先优先取Offer_id下的配置
            PageNavigationVO pageNavigationVO = this.getPageNavigationVOByOfferId(oldServiceOfferId, taskCode, offerType, offerId).getResultObject();

            // 2、为空再取分类下的配置
            if (KiteObjectUtils.isEmpty(pageNavigationVO)) {
                pageNavigationVO = this.getPageNavigationVO(oldServiceOfferId, taskCode, offerType, objId, singleGoodsSku).getResultObject();
            }
            // 2、根据tacheCode 查询
            if (KiteObjectUtils.isEmpty(pageNavigationVO)) {
                pageNavigationVO = this.getPageNavigationVOByOfferId(oldServiceOfferId, tacheCode, offerType, offerId).getResultObject();
            }

            if (KiteObjectUtils.isEmpty(pageNavigationVO)) {
                pageNavigationVO = this.getPageNavigationVO(oldServiceOfferId, tacheCode, offerType, objId, singleGoodsSku).getResultObject();
            }

            // 收入归集导入特殊处理处理
            if (!KiteStringUtils.isEmpty(sceneInstId)) {
                //String sceneActionType = this.querySceneInstService.getExtParameterValue(sceneInstId, "sceneActionType");
                String sceneActionType = (String) CuccExtParameterCache.getExtParameter(sceneInstId, custId, cartId).get("sceneActionType");
                if (!KiteStringUtils.isEmpty(sceneActionType)) {
                    PageNavigationVO groupPageNavigation = this.getPageNavigationVOByOfferId(oldServiceOfferId, sceneActionType, offerType, offerId).getResultObject();
                    // 2、为空再取分类下的配置
                    if (KiteObjectUtils.isEmpty(groupPageNavigation)) {
                        groupPageNavigation = this.getPageNavigationVO(oldServiceOfferId, sceneActionType, offerType, objId, singleGoodsSku).getResultObject();
                    }
                    if (!KiteObjectUtils.isEmpty(groupPageNavigation)) {
                        return ErrorConsts.SUCCESS.getResult(groupPageNavigation);
                    }
                }
            }
            if (KiteStringUtils.isNotEmpty(payDetailFlag) && KiteStringUtils.equals(payDetailFlag, "T")) {
                pageNavigationVO.setServiceOfferId(oldServiceOfferId);
            }

            return ErrorConsts.SUCCESS.getResult(pageNavigationVO);
        }
        // 兼容旧配置
        if (StringUtils.isNotBlank(offerId)) {
            PageNavigationVO result = pageNavigationService.getPageNavigationByOffer(offerId, oldServiceOfferId);
            if (result != null) {
                return ErrorConsts.SUCCESS.getResult(result);
            }
        }

        return ErrorConsts.SUCCESS.getResult(KitePageNavigationCache.get(oldServiceOfferId, offerType));
    }

    private DataResult<PageNavigationVO> getPageNavigationVO(String serviceOfferId, String tacheCode, String offerType, String objId, String singleGoodsSku) {


        // 1、根据商品ID来获取，获取不到，则先根据商品分类来获取，优先取分类下的配置
        // 根据商品ID来获取，优先取商品下的配置 obj_id 可以是分类ID，也可以是offer_id

        PageNavigationVO pageNavigationVO = CuccKitePageNavigationCache
            .get(serviceOfferId, tacheCode, offerType, objId);

        // 2，不存在，则获取，service_offer_id为-1的数据，即表示相同商品，不同业务，不同环节都用同一个模版
        if (Objects.isNull(pageNavigationVO) || KiteStringUtils.isEmpty(pageNavigationVO.getNavigationId())) {
            pageNavigationVO = CuccKitePageNavigationCache.get("-1", tacheCode, offerType, objId);
        }
        // 3、不存在，则获取obj_id为空的数据，即表示所有商品同一业务，不同环节都用同一个模版
        if (Objects.isNull(pageNavigationVO) || KiteStringUtils.isEmpty(pageNavigationVO.getNavigationId())) {
            pageNavigationVO = CuccKitePageNavigationCache.get(serviceOfferId, tacheCode, offerType, null);
        }
        //添加低代码平台控制页面流开关
        if (GeneralSwitchUtils.isSwitchOpened(SwitchConsts.CHECK_LCDP_PAGE_FLOW)) {
            if (Objects.isNull(pageNavigationVO) || KiteStringUtils.isEmpty(pageNavigationVO.getNavigationId())) {
                PageNavigationReqDTO reqDTO = new PageNavigationReqDTO();
                reqDTO.setCateId(objId);
                reqDTO.setServiceOfferId(serviceOfferId);
                reqDTO.setObjId(singleGoodsSku);
                //处理低代码平台解析页面流
                pageNavigationVO = pageNavigationService.parseLcdpPageDefinition(reqDTO);
            }
        }
        // 4，不存在，则获取，service_offer_id为-1，obj_id为空的数据的数据，即表示所有商品不同业务，不同环节，不同商品都用同一个模版
        if (Objects.isNull(pageNavigationVO) || KiteStringUtils.isEmpty(pageNavigationVO.getNavigationId())) {
            pageNavigationVO = CuccKitePageNavigationCache.get("-1", tacheCode, offerType, null);
        }

        if (Objects.nonNull(pageNavigationVO) && KiteStringUtils.isNotEmpty(pageNavigationVO.getNavigationId())) {
            pageNavigationVO.setPageType(DcPublicCache.getCodea("20201202001", tacheCode));
            return ErrorConsts.SUCCESS.getResult(pageNavigationVO);
        }
        return ErrorConsts.SUCCESS.getResult(null);
    }

    private DataResult<PageNavigationVO> getPageNavigationVOByOfferId(String serviceOfferId, String tacheCode, String offerType, String offerId) {


        // 1、根据商品ID来获取，获取不到，则先根据商品分类来获取，优先取分类下的配置
        // 根据商品ID来获取，优先取商品下的配置 obj_id 为offer_id

        PageNavigationVO pageNavigationVO = CuccKitePageNavigationCache
            .get(serviceOfferId, tacheCode, offerType, offerId);

        //添加低代码平台控制页面流开关
        if (GeneralSwitchUtils.isSwitchOpened(SwitchConsts.CHECK_LCDP_PAGE_FLOW)) {
            if (Objects.isNull(pageNavigationVO) || KiteStringUtils.isEmpty(pageNavigationVO.getNavigationId())) {
                PageNavigationReqDTO reqDTO = new PageNavigationReqDTO();
                reqDTO.setServiceOfferId(serviceOfferId);
                reqDTO.setObjId(offerId);
                //处理低代码平台解析页面流
                pageNavigationVO = pageNavigationService.parseLcdpPageDefinition(reqDTO);
            }
        }

        // 2，不存在，则获取，service_offer_id为-1的数据，即表示相同商品，不同业务，不同环节都用同一个模版
        if (Objects.isNull(pageNavigationVO) || KiteStringUtils.isEmpty(pageNavigationVO.getNavigationId())) {
            pageNavigationVO = CuccKitePageNavigationCache.get("-1", tacheCode, offerType, offerId);
        }


        if (Objects.nonNull(pageNavigationVO) && KiteStringUtils.isNotEmpty(pageNavigationVO.getNavigationId())) {
            pageNavigationVO.setPageType(DcPublicCache.getCodea("20201202001", tacheCode));
            return ErrorConsts.SUCCESS.getResult(pageNavigationVO);
        }
        return ErrorConsts.SUCCESS.getResult(null);
    }

    @ApiOperation(value = "生成套餐修改场景对象", notes = "生成套餐修改场景对象")
    @ApiImplicitParams({@ApiImplicitParam(name = "serviceOfferId", value = "服务提供标识", required = true),
        @ApiImplicitParam(name = "templateId", value = "场景模板标识", required = true),
        @ApiImplicitParam(name = "sceneInstId", value = "场景实例标识", required = true),
        @ApiImplicitParam(name = "offerId", value = "销售品标识")
    })
    @GetMapping("/modOffer")
    public DataResult<SceneVO> createModOfferScene(@RequestParam String serviceOfferId, @RequestParam String templateId,
                                                   @RequestParam(required = false) String offerId, @RequestParam String sceneInstId) {
        this.cuccSceneService.getCartIdFromES();

        DataResult<SceneVO> result = new DataResult<SceneVO>();
        if (StringUtil.isBlank(offerId)) {
            offerId = getSpecId(getSceneInst(sceneInstId));
        }
//        OppoToSceneUtils.getInst().putOppoToContext(null,sceneInstId);
        AcceptRequestInDTO acceptRequest = new AcceptRequestInDTO();
        acceptRequest.setSceneInstId(sceneInstId).setSceneTemplateId(templateId).setOfferId(offerId)
            .setServiceOfferId(serviceOfferId);
        operateSceneInstService.putExtParameter(sceneInstId, "changeServiceOfferId", serviceOfferId);
        result = sceneService.callEngine(acceptRequest);
        operateSceneInstService.putExtParameter(sceneInstId, LocalKeyConsts.BUSI_CHANGE, "T");
        operateSceneInstService.putExtParameter(sceneInstId, LocalKeyConsts.BUSI_CHANGE_SCENE_ONE, "F");
        return result;
    }

    @ApiOperation(value = "产品变更提交前刷新场景对象", notes = "产品变更提交前刷新场景对象")
    @ApiImplicitParams({@ApiImplicitParam(name = "serviceOfferId", value = "服务提供标识", required = true),
        @ApiImplicitParam(name = "templateId", value = "场景模板标识", required = true),
        @ApiImplicitParam(name = "sceneInstId", value = "场景实例标识", required = true),
        @ApiImplicitParam(name = "offerId", value = "销售品标识")
    })
    @GetMapping("/modOfferBfCommit")
    public DataResult<SceneVO> refreshModOfferSceneBfCommit(@RequestParam String serviceOfferId, @RequestParam String templateId,
                                                            @RequestParam(required = false) String offerId, @RequestParam String sceneInstId) {

        String initFlag = querySceneInstService.getExtParameterValue(sceneInstId, "afCommonAttrInit", "");
        if (!"T".equals(initFlag)) {
            operateSceneInstService.putExtParameter(sceneInstId, "afCommonAttrInit", "T");
        }
        return this.createModOfferScene(serviceOfferId, templateId, offerId, sceneInstId);
    }

    @ApiOperation(value = "获取场景实例基本信息(如果场景实例缓存不存在，则从购物车和过程实例表还原场景实例)", notes = "获取场景实例基本信息(如果场景实例缓存不存在，则从购物车和过程实例表还原场景实例)")
    @ApiImplicitParams({@ApiImplicitParam(name = "sceneInstId", value = "场景实例id", required = true),
        @ApiImplicitParam(name = "custId", value = "客户id", required = true)
    })
    @GetMapping("/sceneInst")
    public DataResult<KiteSceneInst> getSceneInst(String sceneInstId, String custId) {
        return ErrorConsts.SUCCESS.getResult(querySceneService.getSceneInst(sceneInstId, custId));
    }

    /**
     * 获取场景实例
     *
     * @param sceneInstId 场景实例标识
     * @return
     */
    private KiteSceneInst getSceneInst(String sceneInstId) {
        return querySceneService.getSceneInst(sceneInstId, KiteWebContext.getContext().getCustId());
    }

    /**
     * 获取规格标识
     *
     * @return
     */
    private String getSpecId(KiteSceneInst kiteSceneInst) {
        KiteOfferInst offerInst = querySceneInstService
            .getOfferInst(kiteSceneInst.getCustId(), kiteSceneInst.getRootInstId());

        if (Objects.nonNull(offerInst)) {
            return offerInst.getSpecId();
        } else {
            return "";
        }

    }

    @ApiOperation(value = "获取新场景对象", notes = "获取新场景对象")
    @ApiImplicitParams({@ApiImplicitParam(name = "sceneInstId", value = "场景实例标识", required = true)
    })
    @GetMapping("/newScene")
    public DataResult<SceneVO> refreshScene(@RequestParam String sceneInstId) {
        return ErrorConsts.SUCCESS.getResult(SceneVOCache.get(sceneInstId));
    }

    @ApiOperation(value = "获取进度信息", notes = "获取进度信息")
    @ApiImplicitParams({@ApiImplicitParam(name = "orderId", value = "订单id", required = true)
    })
    @GetMapping("/progressInfo")
    public DataResult<TrackInfoVO> getProgressInfo(@RequestParam String orderId) {
        return ErrorConsts.SUCCESS.getResult(this.queryFlowService.getOrderProgressInfo(orderId));
    }

    @ApiOperation(value = "获取回执信息", notes = "获取回执信息")
    @ApiImplicitParams({@ApiImplicitParam(name = "orderId", value = "订单id", required = true)
    })
    @GetMapping("/receiptInfo")
    public DataResult<ReceiptInfoVO> getReceiptInfo(@RequestParam(value = "orderId") String orderId,
                                                    @RequestParam(value = "taskId") String taskId) {
        return ErrorConsts.SUCCESS.getResult(this.queryReceiptService.getReceiptInfo(orderId, taskId));
    }

    @ApiOperation(value = "获取OSS进度信息", notes = "获取OSS进度信息")
    @ApiImplicitParams({@ApiImplicitParam(name = "orderId", value = "订单id", required = true),
        @ApiImplicitParam(name = "taskCode", value = "任务编码", required = true)
    })
    @GetMapping("/ossProgressInfo")
    public DataResult<OssTrackInfoVO> getOssProgressInfo(@RequestParam String orderId, @RequestParam String taskCode) {
        return ErrorConsts.SUCCESS.getResult(this.queryFlowService.getOssProgressInfo(orderId, taskCode));
    }

    @ApiOperation(value = "获取一站式进度信息", notes = "获取一站式进度信息")
    @ApiImplicitParams({@ApiImplicitParam(name = "orderId", value = "订单id", required = true),
        @ApiImplicitParam(name = "taskCode", value = "任务编码", required = true),
        @ApiImplicitParam(name = "taskId", value = "任务id", required = true)
    })
    @GetMapping("/oneStopProgressInfo")
    public DataResult<OneStopTrackInfoVO> getOneStopProgressInfo(@RequestParam String orderId,
                                                                 @RequestParam String taskCode, @RequestParam String taskId) {
        return ErrorConsts.SUCCESS.getResult(this.queryFlowService.getOneStopProgressInfo(orderId, taskCode, taskId));
    }

    @KiteTransactional
    @ApiOperation(value = "更新购物车状态", notes = "预览时，返回上一步信息录入页面，需要更新购物车状态")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "sceneInstId", value = "场景实例Id", required = true)
    })
    @PostMapping("/updateCartStatus")
    public DataResult<Boolean> updateCartStatus(@RequestParam String sceneInstId) {
        KiteSceneInst kiteSceneInst = this.querySceneInstService.getSceneInst(sceneInstId);
        String askSource = kiteSceneInst.getAskSource();
        String cartId = kiteSceneInst.getCartId();
        if (KiteStringUtils.isEmpty(cartId)) {
            Long staffId = ContextUtil.getUserId();
            // 获取购物车的分片键，调用ES进行查询，暂时先放在登录信息缓存中,方便场景加载的时候从购物车中获取数据需要通过分片键获取 ，后续改动
            IQueryKiteShoppingCartService queryKiteShoppingCartService = SpringUtil
                .getBean(IQueryKiteShoppingCartService.class);
            // 获取分片键 cartId
            Long cartIdl = queryKiteShoppingCartService.getShoppingCartIdByEs(staffId.toString()).getResultObject();
            if (!KiteObjectUtils.isEmpty(cartIdl)) {
                cartId = cartIdl.toString();
            }
        }
        if (!KiteStringUtils.equals(LocalKeyConsts.ASK_SOURCE_ORDER, askSource)) {
            KiteCartStatusModifyEvent kiteCartStatusModifyEvent = new KiteCartStatusModifyEvent(this,
                KiteWebContext.getContext().getCustId(),
                ContextUtil.getUserId().toString(),
                ContextUtil.getLoginInfo().getUserInfo().getUserName(),
                cartId, KeyConsts.SHOPPING_CART_GROUP_STATUS_INPUT, Collections.singletonList(sceneInstId));
            applicationContext.publishEvent(kiteCartStatusModifyEvent);
        }
        return ErrorConsts.SUCCESS.getResult(Boolean.TRUE);
    }

    /**
     * 把当前场景添加到购物车，购物车分组状态是：待录入
     *
     * @param sceneInstId
     */
    private void cacheShoppingCartGroup(String sceneInstId, String cartId) {
        //this.sceneService.cacheShoppingCartGroup(sceneInstId, cartId);
        /*final String userId = ContextUtil.getUserId().toString();
        final String custId = KiteWebContext.getContext().getCustId();
        final String sessionId = ContextUtil.getHttpSessoinId();
        final String transactionId = KiteTransactionUtils.getTransactionId();
        SimpleLoginInfo simpleLoginInfo = ContextUtil.getSimpleLoginInfo();
        if (KiteStringUtils.isEmpty(cartId)) {
            cartId = queryShoppingCartService.getShoppingCartId(userId, custId);
            KiteSceneInst kiteSceneInst = querySceneInstService.getSceneInst(sceneInstId);
            kiteSceneInst.setCartId(cartId);
            operateSceneInstService.setSceneInst(kiteSceneInst);
        }
        String cartStr = cartId;
        CompletableFuture.runAsync(() -> {
            try {
                KiteTransactionUtils.beginTransaction();
                ContextUtil.setHttpSessoinId(sessionId);
                // 兼容接口调用
                ContextUtil.putSimpleLoginInfo2ThreadLocal(simpleLoginInfo);
                operateShoppingCartService
                    .cacheShoppingCartGroup(ContextUtil.getSimpleLoginInfo(), sceneInstId, userId, custId,
                        KeyConsts.SHOPPING_CART_GROUP_STATUS_INPUT, cartStr);
            }
            catch (Exception e) {
//                e.printStackTrace();
                // just log
                //  logger.error(ErrorConsts.SYSTEM_ERROR.getErrorCode(), e, ErrorConsts.SYSTEM_ERROR.getMsg());
            }
            finally {
                KiteTransactionUtils.commit();
                KiteTransactionUtils.remove();
                ContextUtil.removeThreadLocal();
            }

        });*/
    }

}
